﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Diagnostics;
using System.Windows.Forms.Design;
using OpenESSOConfigurator.PresentationLayer.PresentationModels;
using OpenESSOConfigurator.PresentationLayer.Components;
using OpenESSOConfigurator.PresentationLayer.EventBroker;

namespace OpenESSOConfigurator.PresentationLayer.UserControls
{
    public partial class LeftSpine : UserControl, IView
    {
        private int _visibleCount = -1;
        private int _lastCount = -1;
        private int _maxHeight;

        #region Public
        public ItemTreeView ItemTreeView1
        {
            set { itemTreeView1 = value; }
            get { return itemTreeView1; }
        }
        #endregion

        #region Setup
        public LeftSpine()
        {
            InitializeComponent();
            InitializeBaseStackStripHandler(); 
        }
        private void InitializeBaseStackStripHandler()
        {
            this.baseStackStrip1.ItemClicked += new ToolStripItemClickedEventHandler(BaseStackStripItem_Clicked);
            
        }
        private void StackBar_Load(object sender, EventArgs e)
        {
            // Setup
            this.stackStrip1.ItemHeightChanged += new EventHandler(stackStrip1_ItemHeightChanged);

            // Add Overflow items
            AddOverflowItems();

            // Set Height
            InitializeSplitter();

            LeftSpinePresentationModel.Instance.RegisterView(this);
            

        }
        private void AddOverflowItems()
        {
            ToolStripButton item;
            Color trans = Color.FromArgb(238, 238, 238);
            string name;
            string tag;

            // Add items to overflow
            for (int idx = this.stackStrip1.ItemCount - 1; idx >= 0; idx--)
            {
                name = this.stackStrip1.Items[idx].Tag as string;
                tag = this.stackStrip1.Items[idx].Text as string;

                if (null != name)
                {
                    item = new ToolStripButton(GetBitmapResource(name));
                    item.ImageTransparentColor = trans;
                    item.Alignment = ToolStripItemAlignment.Right;
                    item.Name = name;
                    item.Tag = tag;
                    item.MouseEnter += new EventHandler(item_MouseEnter);
                    item.MouseLeave += new EventHandler(item_MouseLeave);
                    this.baseStackStrip1.Items.Add(item);
                }
            }
        }

        void item_MouseEnter(object sender, EventArgs e)
        {
            this.Cursor = Cursors.Hand;
        }

        void item_MouseLeave(object sender, EventArgs e)
        {
            this.Cursor = Cursors.Default;
        }       
        private Bitmap GetBitmapResource(string name)
		{
			return Properties.Resources.ResourceManager.GetObject(name) as Bitmap;
		}
		#endregion

        #region Event Handlers
        private void splitContainer1_Paint(object sender, PaintEventArgs e)
        {
            ProfessionalColorTable pct = new ProfessionalColorTable();
            Rectangle bounds = (sender as SplitContainer).SplitterRectangle;

            int squares;
            int maxSquares = 9;
            int squareSize = 4;
            int boxSize = 2;

            // Make sure we need to do work
            if ((bounds.Width > 0) && (bounds.Height > 0))
            {
                Graphics g = e.Graphics;

                // Setup colors from the provided renderer
                Color begin = pct.OverflowButtonGradientMiddle;
                Color end = pct.OverflowButtonGradientEnd;

                // Make sure we need to do work
                using (Brush b = new LinearGradientBrush(bounds, begin, end, LinearGradientMode.Vertical))
                {
                    g.FillRectangle(b, bounds);
                }

                // Calculate squares
                if ((bounds.Width > squareSize) && (bounds.Height > squareSize))
                {
                    squares = Math.Min((bounds.Width / squareSize), maxSquares);

                    // Calculate start
                    int start = (bounds.Width - (squares * squareSize)) / 2;
                    int Y = bounds.Y + 1;

                    // Get brushes
                    Brush dark = new SolidBrush(pct.GripDark);
                    Brush middle = new SolidBrush(pct.ToolStripBorder);
                    Brush light = new SolidBrush(pct.ToolStripDropDownBackground);

                    // Draw
                    for (int idx = 0; idx < squares; idx++)
                    {
                        // Draw grips
                        g.FillRectangle(dark, start, Y, boxSize, boxSize);
                        g.FillRectangle(light, start + 1, Y + 1, boxSize, boxSize);
                        g.FillRectangle(middle, start + 1, Y + 1, 1, 1);
                        start += squareSize;
                    }

                    dark.Dispose();
                    middle.Dispose();
                    light.Dispose();
                }
            }
        }
        void stackStrip1_ItemHeightChanged(object sender, EventArgs e)
        {
            InitializeSplitter();
        }
        private void stackStripSplitter_SplitterMoved(object sender, SplitterEventArgs e)
        {
            if ((_maxHeight > 0) && ((this.splitContainer1.Height - e.SplitY) > _maxHeight))
            {
                // Limit to max height
                this.splitContainer1.SplitterDistance = this.splitContainer1.Height - _maxHeight;

                // Set to max
                _visibleCount = this.stackStrip1.ItemCount;
            }
            else if ((_visibleCount > 0) && (this.stackStrip1.ItemCount > 0))
            {
                // Make sure overflow is correct
                _visibleCount = (this.stackStrip1.Height / this.stackStrip1.ItemHeight);

                // See if this changed
                if (_lastCount != _visibleCount)
                {
                    int count = this.baseStackStrip1.Items.Count;

                    // Update overflow items
                    for (int idx = 1; idx < count; idx++)
                    {
                        this.baseStackStrip1.Items[idx].Visible = (idx < (count - _visibleCount));
                    }

                    // Update last
                    _lastCount = _visibleCount;
                }
            }
        }
        //[EventPublication("topic://LeftSpine/LeftSpineToolStripBtnClick")]
        //public event EventHandler LeftSpineToolStripBtnClick;
        private void ToolStripBtn_Clicked(object sender, EventArgs e)
        {
           this.toolStripLabel1.Text = " "+((ToolStripButton)sender).Text;
           LeftSpinePresentationModel.Instance.SelectedButton = (ToolStripButton)sender;
           //if (LeftSpineToolStripBtnClick != null)
           //    LeftSpineToolStripBtnClick(sender, e);
        }
        private void BaseStackStripItem_Clicked(object sender, ToolStripItemClickedEventArgs e)
        {
            ToolStripButton toolstrBtn = new ToolStripButton();
            toolstrBtn.Text = e.ClickedItem.Tag.ToString();
            toolstrBtn.Tag = e.ClickedItem.Name;
            ToolStripBtn_Clicked(toolstrBtn, (EventArgs)e);
            foreach (ToolStripButton btn in this.stackStrip1.Items)
                if (btn.Text.Equals(toolstrBtn.Text))
                    btn.Checked = true;
        }
        #endregion

        #region Private API
        private void InitializeSplitter()
        {
            // Set slider increment
            if (this.stackStrip1.ItemHeight > 0)
            {
                this.splitContainer1.SplitterIncrement = this.stackStrip1.ItemHeight;

                // Find visible count
                if (_visibleCount < 0)
                {
                    _visibleCount = this.stackStrip1.InitialDisplayCount;
                }

                // Setup BaseStackStrip
                this.baseStackStrip1.Height = this.stackStrip1.ItemHeight;

                // Set splitter distance
                int min = this.stackStrip1.ItemHeight + this.baseStackStrip1.Height;
                int distance = this.splitContainer1.Height - this.splitContainer1.SplitterWidth - ((_visibleCount * this.stackStrip1.ItemHeight) + this.baseStackStrip1.Height);

                // Set Max
                _maxHeight = (this.stackStrip1.ItemHeight * this.stackStrip1.ItemCount) + this.splitContainer1.Height + this.splitContainer1.SplitterWidth;

                // In case it's sized too small on startup
                if (distance < 0)
                {
                    distance = min;
                }

                // Set Min/Max
                this.splitContainer1.SplitterDistance = distance;
                this.splitContainer1.Panel1MinSize = min;
            }
        }
        #endregion

        private void toolStripButton_MoseEnter(object sender, EventArgs e)
        {
            this.Cursor = System.Windows.Forms.Cursors.Hand;
        }

        private void tooStripButton_MoseLeave(object sender, EventArgs e)
        {
            this.Cursor = System.Windows.Forms.Cursors.Default;
        }


    }
}
